#include "dominion.h"
#include "dominion_helpers.h"
#include "testCards.h"
#include "rngs.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <math.h>
int testSteward(struct gameState *state,int choice1,int choice2,int choice3)
{
    struct gameState *oldState = newGame();
    *oldState = *state;
    int i,handPos=-1;
    for(i=0;i<state->handCount[state->whoseTurn];i++)
    {
        if(state->hand[state->whoseTurn][i] == steward)
        {
            handPos = i;
            break;
        }
    }
    if(handPos<0)
    {
        printf("steward not in hand of current player\n");
        free(oldState);
        return -1;
    }
    if(cardEffect(steward,choice1,choice2,choice2,state,handPos,0) == -1)
    {
        printf("cardEffect returned -1\n");
        free(oldState);
        return -1;
    }
    if(choice1 == 1)
    {
        if(state->handCount[state->whoseTurn] ==
           oldState->handCount[state->whoseTurn]+1
          )
        {
            printf("steward worked correctly\n");
            free(oldState);
            return 0;
        }
        printf("steward failed\n");
        free(oldState);
        return -1;
    }
    if(choice1 == 2)
    {
        if(state->coins == oldState->coins+2)
        {
            printf("steward worked correctly on choice1=2\n");
            free(oldState);
            return 0;
        }
        printf("steward failed\n");
        free(oldState);
        return -1;
    }
    if(choice1 == 3)
    {
        if(state->handCount[state->whoseTurn]==
           oldState->handCount[state->whoseTurn]-3&&
           state->discardCount[state->whoseTurn] ==
           oldState->discardCount[state->whoseTurn])
        {
            printf("steward worked correctly on choice1=3i\n");
            free(oldState);
            return 0;
        }
        printf("steward failed\n");
        free(oldState);
        return -1;
    }
    printf("steward failed\n");
    free(oldState);
    return -1;
}

int testSmithy(struct gameState *state)
{
    struct gameState *oldState = newGame();
    *oldState = *state;
    int i,handPos=-1;
    for(i=0;i<state->handCount[state->whoseTurn];i++)
    {
        if(state->hand[state->whoseTurn][i] == smithy)
        {
            handPos = i;
            break;
        }
    }
    if(handPos<0)
    {
        printf("smithy not in hand of current player\n");
        free(oldState);
        return -1;
    }

    if(cardEffect(smithy,0,0,0,state,handPos,0) == -1)
    {
        printf("cardEffect returned -1\n");
        free(oldState);
        return -1;
    }
    if(state->handCount[state->whoseTurn] ==
       oldState->handCount[state->whoseTurn]+3)
    {
        printf("smithy worked correctly\n");
        free(oldState);
        return 0;
    }
    else
    {
        printf("Smithy failed\n");
        free(oldState);
        return -1;
    }
}


int testMinion(struct gameState *state, int supplyChoice, int supplyChoice2){

	struct gameState *oldState = newGame();
	*oldState = *state;
	int numActions = state->numActions;
	int numCoins = state->coins;
	int discardPile = state->discardCount[0];
	int numCards = state->handCount[1];
	int i, handPos=-1;
	for(i=0; i<state->handCount[state->whoseTurn];i++)
	{
		if(state->hand[state->whoseTurn][i] == minion){
		handPos = i;
		break;
		}
	}
	
	    if(handPos<0)
    {
        printf("minion not in hand of current player\n");
        free(oldState);
        return -1;
    }
    if(state->supplyCount[supplyChoice] == -1)
    {
        printf("supply choice not in game\n");
    }
	
	if(cardEffect(remodel,supplyChoice,supplyChoice2,0,state,handPos,0) == -1)
    {
        printf("cardEffect returned -1\n");
        free(oldState);
        return -1;
    }
	
	//check actions
	if(state->numActions == numActions)
		printf("Minion Actions Test Passed.\n");
	else{
		printf("Minion Actions Test Failed.\n");
		return -1;
		}
		
	//test player choice
	if((state->coins + 2 == numCoins) || state->discardCount[0] + 4 == discardPile)
		printf("Minion Test2 Passed.\n");
	else{
		printf("Minion Test2 Failed.\n");
		return -1;
		}
	
	//test other player's hand
	if(numCards <= 4) {
		if(state->handCount[1] == numCards){
			printf("Other player's handCount is Correct.\n");
			}
		else{
			printf("Other player's handCount is  Not Correct.\n");
			return -1;
		}
		}
	else
		if(state->handCount[1] == 4){
			printf("Other player's handCount is Correct.\n");
			}
		else{
			printf("Other player's handCount is  Not Correct.\n");
			return -1;
			}
		
	return 0;

}

int testRemodel(struct gameState *state, int supplyChoice, int supplyChoice2){

	struct gameState *oldState = newGame();
	*oldState = *state;
	int discardPile = oldState->discardCount[oldState->whoseTurn];
	int i, handPos=-1;
	for(i=0; i<state->handCount[state->whoseTurn];i++)
	{
		if(state->hand[state->whoseTurn][i] == remodel){
		handPos = i;
		break;
		}
	}
	
	    if(handPos<0)
    {
        printf("remodel not in hand of current player\n");
        free(oldState);
        return -1;
    }
    if(state->supplyCount[supplyChoice] == -1)
    {
        printf("supply choice not in game\n");
    }
	
	if(cardEffect(remodel,supplyChoice,supplyChoice2,0,state,handPos,0) == -1)
    {
        printf("cardEffect returned -1\n");
        free(oldState);
        return -1;
    }
	
	//check discard pile
	if(discardPile + 1 == state->discardCount[state->whoseTurn])
		printf("Discard Count Test Passed.\n");
	else{
		printf("Discard Count Test Failed.\n");
		return -1;
		}
		
	
	return 0;
	

}

int testFeast(struct gameState *state, int supplyChoice)
{
	struct gameState *oldState = newGame();
	*oldState = *state;
	int i, handPos=-1;
	for(i=0; i<state->handCount[state->whoseTurn];i++)
	{
		if(state->hand[state->whoseTurn][i] == feast){
		handPos = i;
		break;
		}
	}
	
	    if(handPos<0)
    {
        printf("feast not in hand of current player\n");
        free(oldState);
        return -1;
    }
    if(state->supplyCount[supplyChoice] == -1)
    {
        printf("supply choice not in game\n");
    }
	printf("4\n");
	if(cardEffect(feast,supplyChoice,0,0,state,handPos,0) == -1)
    {
		printf("cardEffect returned -1\n");
        free(oldState);
        return -1;
    }
	printf("5\n");
	return 0;
	
}

int testEmbargo(struct gameState *state,int supplyChoice)
{
    struct gameState *oldState = newGame();
    *oldState = *state;
    int i,handPos=-1;
    for(i=0;i<state->handCount[state->whoseTurn];i++)
    {
        if(state->hand[state->whoseTurn][i] == embargo)
        {
            handPos = i;
            break;
        }
    }
    if(handPos<0)
    {
        printf("embargo not in hand of current player\n");
        free(oldState);
        return -1;
    }
    if(state->supplyCount[supplyChoice] == -1)
    {
        printf("supply choice not in game\n");
    }
    if(cardEffect(embargo,supplyChoice,0,0,state,handPos,0) == -1)
    {
        printf("cardEffect returned -1\n");
        free(oldState);
        return -1;
    }
/*    printf("Coins: %d\t%d\n", state->coins, oldState->coins);
    printf("handCount: %d\t%d\n",
           state->handCount[state->whoseTurn],
           oldState->handCount[state->whoseTurn]);
    printf("discardCount %d\t%d\n",
           state->discardCount[state->whoseTurn],
           oldState->discardCount[state->whoseTurn]);
    printf("embargoTokens: %d\t%d\n",
            state->embargoTokens[supplyChoice],
            oldState->embargoTokens[supplyChoice]);

*/
    if(state->coins == oldState->coins+2 &&
       state->handCount[state->whoseTurn] ==
       oldState->handCount[state->whoseTurn]-1 &&
       state->discardCount[state->whoseTurn] ==
       oldState->discardCount[state->whoseTurn] &&
       state->embargoTokens[supplyChoice] ==
       oldState->embargoTokens[supplyChoice]+1)
    {
        printf("embargo worked correctly\n");
        free(oldState);
        return 0;
    }
    free(oldState);
    return -1;


}

int testTreasure_Map(struct gameState *state)
{
    struct gameState *oldState = newGame();
    *oldState = *state;
    int i,secondTreasure=-1,handPos=-1;
    for(i=0;i<state->handCount[state->whoseTurn];i++)
    {
        if(state->hand[state->whoseTurn][i] == treasure_map)
        {
            handPos = i;
            break;
        }
    }
    if(handPos<0)
    {
        printf("treasure_map not in hand of current player\n");
        free(oldState);
        return -1;
    }
    for(i=0;i<state->handCount[state->whoseTurn];i++)
    {
        if(i==handPos){continue;}
        if(state->hand[state->whoseTurn][i] == treasure_map)
        {
            secondTreasure = 1;
            break;
        }
    }
    if(secondTreasure == -1){
        printf("Only one treasure card in hand\n");
        //free(oldState);
        //return -1;
    }
    if(cardEffect(treasure_map,0,0,0,state,handPos,0) == -1)
    {
        printf("cardEffect returned -1\n");
        free(oldState);
        return -1;
    }

    if(state->deckCount[state->whoseTurn] ==
       oldState->deckCount[state->whoseTurn]+4 &&
       state->handCount[state->whoseTurn] ==
       oldState->handCount[state->whoseTurn]-2
       )
    {
       for(i=oldState->deckCount[state->whoseTurn];
           i<state->deckCount[state->whoseTurn];i++)
       {
           printf("%d\n",state->deck[state->whoseTurn][i]);
            if(state->deck[state->whoseTurn][i] != gold)
            {
                printf("Didn't put 4 gold cards on top of deck\n");
                free(oldState);
                return -1;
            }
       }
       printf("treasure_map worked correctly\n");
       free(oldState);
       return 0;
    }
    printf("treasure_map failed on deckcount or handcount check\n");
    free(oldState);
    return -1;

}
int testSea_Hag(struct gameState *state)
{
    struct gameState *oldState = newGame();
    *oldState = *state;
    int i,handPos=-1;
    for(i=0;i<state->handCount[state->whoseTurn];i++)
    {
        if(state->hand[state->whoseTurn][i] == sea_hag)
        {
            handPos = i;
            break;
        }
    }
    if(handPos<0)
    {
        printf("Sea_Hag not in hand of current player\n");
        free(oldState);
        return -1;
    }
    if(cardEffect(sea_hag,0,0,0,state,handPos,0) == -1)
    {
        printf("cardEffect returned -1\n");
        free(oldState);
        return -1;
    }
    for(i=0;i<state->numPlayers;i++)
    {
        if(i == state->whoseTurn){continue;}
//        printf("%d\t%d\n%d\t%d\n%d\n", state->discardCount[i],oldState->discardCount[i],state->deckCount[i],oldState->deckCount[i],state->deck[i][state->deckCount[i]-1]);
        if(!(state->discardCount[i] == oldState->discardCount[i]+1 &&
           state->deckCount[i] == oldState->deckCount[i] &&
           state->deck[i][state->deckCount[i]-1] == curse))
        {
            printf("sea_hag failed\n");
            free(oldState);
            return -1;
        }
    }
    printf("sea_hag worked correctly\n");
    free(oldState);
    return 0;
}
int testSalvager(struct gameState *state,int choice1)
{
    struct gameState *oldState = newGame();
    *oldState = *state;
    int i,salvagedCard,salvagedCardPos, handPos=-1;
    for(i=0;i<state->handCount[state->whoseTurn];i++)
    {
        if(state->hand[state->whoseTurn][i] == salvager)
        {
            handPos = i;
            break;
        }
    }
    if(handPos<0)
    {
        printf("Salvager not in hand of current player\n");
        free(oldState);
        return -1;
    }
    //if(state->handCount[state->whoseTurn] > 1)
    //{
 //       printf("TESTING1");
    //    salvagedCardPos = (rand() % state->handCount[state->whoseTurn]);
   //     while(salvagedCardPos == handPos)
     //   {
      //   salvagedCardPos = (rand() % state->handCount[state->whoseTurn]);
    //    }
     //   salvagedCard = state->hand[state->whoseTurn][salvagedCardPos];
  //  }
  
//    printf("%d\t%d\n",salvagedCard,salvagedCardPos);
    if(cardEffect(salvager,choice1,0,0,state,handPos,0) == -1)
    {
        printf("cardEffect returned -1\n");
        free(oldState);
        return -1;
    }
    //printf("%d\t%d\n%d\t%d\n%d\t%d\n",state->numBuys,oldState->numBuys,state->discardCount[state->whoseTurn],oldState->discardCount[state->whoseTurn],state->handCount[state->whoseTurn],oldState->handCount[state->whoseTurn]);
    if(state->numBuys == oldState->numBuys+1 &&
       state->discardCount[state->whoseTurn] ==
       oldState->discardCount[state->whoseTurn]+1 &&
      (state->handCount[state->whoseTurn] ==
       oldState->handCount[state->whoseTurn]-2 ||
       state->handCount[state->whoseTurn] == 0)
      )
    {
//        printf("TESTING2");
        if(1)
        {
            if(state->coins == (oldState->coins
               + getCost(choice1)))
            {
                printf("Salvager worked correctly");
                free(oldState);
                return 0;
            }
            free(oldState);
            return -1;
        }
        printf("Salvager worked correctly");
        free(oldState);
        return 0;
    }
//    printf("TEST3");
    free(oldState);
    return -1;
}

int testOutpost(struct gameState *state)
{
    struct gameState *oldState = newGame();
    *oldState = *state;
    int i,handPos=-1;
    for(i=0;i<state->handCount[state->whoseTurn];i++)
    {
        if(state->hand[state->whoseTurn][i] == outpost)
        {
            handPos = i;
            break;
        }
    }
    if(handPos<0)
    free(oldState);
    return -1;
}
int testCutpurse(struct gameState *state)
{
    struct gameState *oldState = newGame();
    *oldState = *state;
    int i,j, handPos=-1;
    for(i=0;i<state->handCount[state->whoseTurn];i++)
    {
        if(state->hand[state->whoseTurn][i] == cutpurse)
        {
            handPos = i;
            break;
        }
    }
    if(handPos<0)
    {
        printf("cutpurse not in hand of current player\n");
        free(oldState);
        return -1;
    }
//    printf("%d %d\n",state->coins,oldState->coins);
    if(cardEffect(cutpurse,0,0,0,state,handPos,0)== -1)
    {
        printf("cardEffect returned -1\n");
        free(oldState);
        return -1;
    }
//    printf("Coins: %d\tOld: %d\n",state->coins,oldState->coins);
    if(state->handCount[state->whoseTurn] ==
       oldState->handCount[state->whoseTurn]-1 &&
       state->coins == oldState->coins+2)
    {
        for(i=0;i<state->numPlayers;i++)
        {
            if(i==state->whoseTurn){continue;}
            for(j=0;j<oldState->handCount[i];j++)
            {
                if(oldState->hand[i][j] == copper)
                {
                    if(!(state->handCount[i] ==
                        oldState->handCount[i]-1 ||
                        state->handCount[i] == 0))
                    {
                        printf("cutpurse failed to remove cards from                                  other players hands\n");
                        free(oldState);
                        return -1;
                    }
                    break;
                }
            }

        }
        printf("cutpurse worked correctly\n");
        free(oldState);
        return 0;
    }
    else
    {
        printf("cutpurse failed to either give coins to the player or remove the card from hand\n");
        free(oldState);
        return -1;
    }



}

